from django.http import JsonResponse, HttpResponseBadRequest
from django.shortcuts import render

# Create your views here.
from django.views import View
import json
from django import http
from django_redis import get_redis_connection
from redis import Redis

from apps.goods.models import SKU
from utils.views import LoginRequiredJSONMixin


class CartsView(LoginRequiredJSONMixin, View):
    """购物车管理"""

    # 增加
    def post(self, requst):
        #  - 接收参数 校验
        data_dict = json.loads(requst.body)
        sku_id = data_dict.get("sku_id")
        count = data_dict.get("count")
        selected = data_dict.get("selected", True)  # 如果没有传 默认是选中

        # 判断参数是否齐全
        if not all([sku_id, count]):
            return HttpResponseBadRequest('缺少必传参数')
        # 判断sku_id是否存在
        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return HttpResponseBadRequest('商品不存在')
        # 判断count是否为数字
        try:
            count = int(count)
        except Exception:
            return HttpResponseBadRequest('参数count有误')
        # 判断selected是否为bool值
        if selected:
            if not isinstance(selected, bool):
                return HttpResponseBadRequest('参数selected有误')

        user = requst.user

        # - 添加数据到redis
        redis_conn: Redis = get_redis_connection('carts')
        pl = redis_conn.pipeline()
        # hincrby 这里是对key为sku_id的值 记性累加count计算
        pl.hincrby('carts_%s' % user.id, sku_id, count)  # carts_userid : {sku_id1:10, sku_id2:1,sku_id3:5}
        if selected:
            pl.sadd('selected_%s' % user.id, sku_id)

        pl.execute()

        return JsonResponse({'code': 0, 'errmsg': '添加购物车成功'})

    # 查看
    def get(self, request):
        user = request.user
        redis_conn: Redis = get_redis_connection('carts')
        # 获取hash的数据
        redis_carts = redis_conn.hgetall('carts_%s' % user.id)
        print("redis_carts", redis_carts)
        # 获取set里的数据
        carts_selected = redis_conn.smembers('selected_%s' % user.id)
        # 把redis取出的数据 转为字典 合并储存 方便后面获取
        cart_dict = {}
        for sku_id, count in redis_carts.items():
            # sku_id和count当前是bytes类型 直接转为int
            cart_dict[int(sku_id)] = {
                "count": int(count),
                "selected": sku_id in carts_selected
            }

        # 根据id查询具体sku数据
        # 获取所有的skuid
        sku_ids = redis_carts.keys()
        # 获取所有的sku对象
        skus = SKU.objects.filter(id__in=sku_ids)
        cart_skus = []
        for sku in skus:
            cart_skus.append({
                "id": sku.id,
                "name": sku.name,
                "default_image_url": sku.default_image.url,  # 图片路径
                "price": sku.price,  # 价格
                "count": cart_dict.get(sku.id).get('count'),  # 数量
                "selected": cart_dict.get(sku.id).get('selected')  # 是否被选中
            })

        return JsonResponse({"cart_skus": cart_skus, 'code': 0, 'errmsg': 'ok'})

    # 修改
    def put(self, request):
        # 接收参数
        json_dict = json.loads(request.body)
        sku_id = json_dict.get('sku_id')
        count = json_dict.get('count')
        selected = json_dict.get('selected', True)

        # 判断参数是否齐全
        if not all([sku_id, count]):
            return http.HttpResponseBadRequest('缺少必传参数')
        # 判断sku_id是否存在
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.HttpResponseBadRequest('商品sku_id不存在')

        # 判断count是否为数字
        try:
            count = int(count)
        except Exception:
            return http.HttpResponseBadRequest('参数count有误')

        user = request.user
        # 用户已登录,修改redis购物车
        redis_conn:Redis = get_redis_connection('carts')
        pl = redis_conn.pipeline()
        # 因为接口设计为幂等的,直接覆盖
        pl.hset('carts_%s' % user.id, sku_id, count)
        # 是否选中
        if selected:
            # 选中添加
            pl.sadd('selected_%s' % user.id, sku_id)
        else:
            # 没选中删除
            pl.srem('selected_%s' % user.id, sku_id)
        pl.execute()
        # 创建响应对象
        cart_sku = {
            'id': sku_id,
            'count': count,
            'selected': selected,
            'name': sku.name,
            'default_image_url': sku.default_image.url,
            'price': sku.price,
            'amount': sku.price * count,
        }
        return JsonResponse({'code': 0, 'errmsg': '修改购物车成功', 'cart_sku': cart_sku})

    # 删除
    def delete(self, request):
        # 接收参数
        json_dict=json.loads(request.body)
        sku_id=json_dict.get('sku_id')
        # 判断sku_id是否存在
        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.HttpResponseBadRequest('商品不存在')

        # 判断用户是否登录
        user = request.user

        # 用户未登录，删除redis购物车
        redis_conn = get_redis_connection('carts')
        pl = redis_conn.pipeline()
        # 删除键，就等价于删除了整条记录
        pl.hdel('carts_%s' % user.id, sku_id)
        pl.srem('selected_%s' % user.id, sku_id)
        pl.execute()

        # 删除结束后，没有响应的数据，只需要响应状态码即可
        return JsonResponse({'code': 0, 'errmsg': '删除购物车成功'})


# 全选
class CartsSelectAllView(LoginRequiredJSONMixin,View):
    def put(self,request):
        # 接收参数
        json_dict=json.loads(request.body)
        selected=json_dict.get('selected',True)

        # 校验参数
        if selected:
            if not isinstance(selected,bool):
                return http.HttpResponseBadRequest('参数selected有误')

        user=request.user
        redis_conn=get_redis_connection('carts')
        cart=redis_conn.hgetall('carts_%s' % user.id)
        # 所有购物车的id
        sku_id_list=cart.keys()
        if selected:
            # 全选
            redis_conn.sadd('selected_%s' % user.id,*sku_id_list)
        else:
            # 取消全选
            redis_conn.srem('selected_%s' % user.id,*sku_id_list)

        return JsonResponse({'code':0,'errmsg':'全选购物车成功'})

# 商品页面右上角购物车
class CartsSimpleView(View):
    def get(self,request):
        user=request.user
        # 查询redis购物车
        redis_conn: Redis = get_redis_connection('carts')
        redis_carts = redis_conn.hgetall('carts_%s' % user.id)
        carts_selected = redis_conn.smembers('selected_%s' % user.id)
        # # 把redis取出的数据 转为字典 合并储存 方便后面获取
        cart_dict = {}
        for sku_id, count in redis_carts.items():
            cart_dict[int(sku_id)] = {
                'count': int(count),
                'selected': sku_id in carts_selected
            }

        # 根据id查询具体sku数据
        # 获取所有的skuid
        sku_ids = redis_carts.keys()
        # 获取所有的sku对象
        skus = SKU.objects.filter(id__in=sku_ids)

        cart_skus = []

        for sku in skus:
            cart_skus.append({
                'id':sku.id,
                'name':sku.name,
                'count':cart_dict.get(sku.id).get('count'),
                'default_image_url': sku.default_image.url,
            })

        # 响应json列表数据
        return JsonResponse({'code':0, 'errmsg':'OK', 'cart_skus':cart_skus})
